/* eslint-disable no-unused-expressions */
/*
 * @Author: AskMeWhy
 * @Date:   2020-05-12 16:56:25
 * @Last Modified by: AskMeWhy
 * @Last Modified time: 2021-01-13 15:31:33
 */

const base64 = require("./upload/base64.js"); // Base64,hmac,sha1,crypto相关算法
require("./upload/hmac.js");
require("./upload/sha1.js");
const Crypto = require("./upload/crypto.js");

const getPolicyBase64 = function (option) {
    const date = new Date();
    date.setHours(date.getHours() + option.timeout);
    const srcT = date.toISOString();
    const policyText = {
        expiration: srcT, // 设置该Policy的失效时间，超过这个失效时间之后，就没有办法通过这个policy上传文件了
        conditions: [
            ["content-length-range", 0, option.limit], // 设置上传文件的大小限制,10mb
        ],
    };

    const policyBase64 = base64.encode(JSON.stringify(policyText));
    return policyBase64;
};

const getSignature = function (policyBase64, option) {
    const accesskey = option.AccessKeySecret;

    const bytes = Crypto.HMAC(Crypto.SHA1, policyBase64, accesskey, {
        asBytes: true,
    });
    const signature = Crypto.util.bytesToBase64(bytes);

    return signature;
};

const wxUploadFile = (curFile, option, files, type = "file") => {
    const _suffix = curFile.filePath.substring(curFile.filePath.lastIndexOf("."));
    const aliyunFileName = curFile.dir + +new Date() + Math.floor(Math.random() * 150) + _suffix;
    const aliyunServerURL = option.action; // OSS地址，需要https
    const accessId = option.OSSAccessKeyId;
    const policyBase64 = getPolicyBase64(option);
    const signature = getSignature(policyBase64, option); // 获取签名
    const resData = {
        ...curFile,
        status: "uploading",
        url: aliyunServerURL,
        fileName: aliyunFileName,
    };
    if (type === "cover") {
        resData.coverFileName = aliyunFileName;
    }
    return new Promise(resolve => {
        if (resData.size > option.limit) {
            resData.status = "fail";
            option.afterUpload && option.afterUpload(resData, files, ["limit"], type);
            resolve(resData);
            return;
        }
        option.beforeUpload && option.beforeUpload(resData, files, [], type);
        wx.uploadFile({
            url: aliyunServerURL, // 开发者服务器 url
            filePath: curFile.filePath, // 要上传文件资源的路径
            name: "file", // 必须填file
            formData: {
                key: aliyunFileName,
                policy: policyBase64,
                OSSAccessKeyId: accessId,
                signature,
                success_action_status: "200",
            },
            success(res) {
                if (res.statusCode !== 200) {
                    resData.status = "fail";
                    option.afterUpload && option.afterUpload(resData, files, [], type);
                    resolve(resData);
                    return;
                }
                resData.src = aliyunServerURL + "/" + aliyunFileName;
                resData.status = "success";
                option.afterUpload && option.afterUpload(resData, files, [], type);
                resolve(resData);
            },
            fail(err) {
                console.log("err", err);
                resData.status = "fail";
                option.afterUpload && option.afterUpload(resData, files, [], type);
                resolve(resData);
            },
        });
    });
};

const _uploadFile = async (files, index = 0, option) => {
    let res = [];
    if (files.length === 0) {
        return res;
    }
    if (files[index].type === "cover") {
        const responseCover = await wxUploadFile({
            ...files[index],
            filePath: files[index].cover,
        }, option, files, files[index].type);
        if (responseCover.status === "fail") {
            files[index].status = "fail";
            option.afterUpload && option.afterUpload(files[index], files, []);
            return res;
        }
    }
    const response = await wxUploadFile(files[index], option, files);
    res.push(response);
    index++;
    if (index <= files.length - 1) {
        const _r = await _uploadFile(files, index, option);
        res = res.concat(_r);
    }
    return res;
};

export const uploadFile = async (files, option = {}) => {
    files = files.map(cur => ({
        ...cur,
        status: "pending",
    }));
    option.onReady && option.onReady(files);
    option.AccessKeySecret = "XfazE3VCtt1eSvc6YO3cTpg0hqLjKM"; // AccessKeySecret 去你的阿里云上控制台上找
    option.OSSAccessKeyId = "LTAIDcZHLQdHY4V6"; // AccessKeyId 去你的阿里云上控制台上找
    const res = await _uploadFile(files, 0, option);
    return res;
};
